package service

import (
	"errors"
	"strconv"

	"gitee.com/cyanbleeze/go-image-management/global"
	"gitee.com/cyanbleeze/go-image-management/internal/model"
	"gitee.com/cyanbleeze/go-image-management/pkg/app"
)

type CommentRequest struct {
	ID uint `json:"id,omitempty" binding:"required,min=1"`
}

type CommentListRequest struct {
	PictureID uint `form:"picture_id" json:"picture_id,omitempty" binding:"required,min=1"`
}

type CreateCommentRequest struct {
	Content   string `json:"content,omitempty" binding:"required,min=1"`
	PictureID uint   `json:"picture_id,omitempty" binding:"required,min=1"`
}

type UpdateCommentRequest struct {
	ID        uint   `json:"id,omitempty" binding:"required,min=1"`
	Content   string `json:"content,omitempty" binding:"required,min=1"`
	PictureID uint   `json:"picture_id,omitempty"`
}

type DeleteCommentRequest struct {
	ID        uint `json:"id" binding:"required,min=1"`
	PictureID uint `json:"picture_id,omitempty"`
}
type CountCommentsRequest struct {
	PictureID uint `json:"picture_id,omitempty"`
}
type Comment struct {
	*model.Comment
	Username string `json:"username,omitempty"`
	Nickname string `json:"nickname,omitempty"`
}

func (svc *Service) CreateComment(params *CreateCommentRequest) error {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return errors.New("登录用户信息不存在")
	}
	err := svc.dao.CreateComment(
		params.Content,
		userID.(uint),
		params.PictureID,
	)
	if err != nil {
		return err
	}
	key := "comment_count_" + strconv.Itoa(int(params.PictureID))
	global.RedisEngine.Incr(svc.ctx, key).Result()
	return nil
}

func (svc *Service) UpdateComment(params *UpdateCommentRequest) error {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return errors.New("登录用户信息不存在")
	}
	return svc.dao.UpdateComment(
		params.ID,
		params.Content,
		userID.(uint),
		params.PictureID,
	)
}

func (svc *Service) DeleteComment(params *DeleteCommentRequest) error {
	userID, exist := svc.ctx.Get("userID")
	if !exist {
		return errors.New("登录用户信息不存在")
	}
	err := svc.dao.DeleteComment(params.ID, userID.(uint))
	if err != nil {
		return err
	}
	key := "comment_count_" + strconv.Itoa(int(params.PictureID))
	global.RedisEngine.Decr(svc.ctx, key).Result()
	return nil
}

func (svc *Service) CountComments(params *CountCommentsRequest) (int, error) {
	key := "comment_count_" + strconv.Itoa(int(params.PictureID))
	val, err := global.RedisEngine.Get(svc.ctx, key).Result()
	if err != nil {
		count, countErr := svc.dao.CountCommentListByPictureID(params.PictureID)
		if countErr != nil {
			return 0, countErr
		}
		global.RedisEngine.Set(svc.ctx, key, count, 0)
		return count, countErr
	}
	return strconv.Atoi(val)
}

func (svc *Service) GetCommentList(params *CommentListRequest, page *app.Pager) ([]*Comment, int, error) {
	_, exist := svc.ctx.Get("userID")
	if !exist {
		return nil, 0, errors.New("登录用户信息不存在")
	}
	count, countErr := svc.CountComments(&CountCommentsRequest{
		PictureID: params.PictureID,
	})
	if countErr != nil {
		return nil, 0, countErr
	}
	commentList, listErr := svc.dao.GetCommentListByPictureID(params.PictureID, page.Page, page.PageSize)
	if listErr != nil {
		return nil, 0, listErr
	}
	var ids [][]interface{}
	for _, c := range commentList {
		ids = append(ids, []interface{}{c.UserID})
	}
	users, userErr := svc.dao.GetUserListInID(ids, page.Page, page.PageSize)
	if userErr != nil {
		return nil, 0, userErr
	}
	exCList := make([]*Comment, 0, 5)
	for i := 0; i < len(commentList); i++ {
		var user *model.User = users[0]
		for j := 0; j < len(users); j++ {
			if users[j].ID == commentList[i].UserID {
				user = users[j]
				break
			}
		}
		exC := Comment{
			Comment:  commentList[i],
			Username: user.Username,
			Nickname: user.Nickname,
		}
		exCList = append(exCList, &exC)
	}
	return exCList, count, nil
}
